using System.Windows.Input;


    public class AsyncRelayCommand<T> : ICommand
    {
        private readonly Func<T?, bool> _canExecute;
        private readonly Func<T?, Task> _execute;
        private bool _isExecuting;

        public AsyncRelayCommand(Func<T?, Task> execute, Func<T?, bool> canExecute = null!)
        {
            _execute=execute??throw new ArgumentNullException(nameof(execute));
            _canExecute=canExecute;
        }

        public event EventHandler? CanExecuteChanged
        {
            add { CommandManager.RequerySuggested+=value; }
            remove { CommandManager.RequerySuggested-=value; }
        }

        public bool CanExecute(object? parameter)
        {
            if (_canExecute==null)
                return true;
            if (parameter is T t) return _canExecute(t);
            return _canExecute(default);
        }

        public async void Execute(object? parameter)
        {
            if (!CanExecute(parameter))
                return;

            if (!CanExecute(parameter))
                return;
            if (parameter is T t)
                await _execute(t);
            else
                await _execute(default);
        }

        public void OnCanExecuteChanged()
        {
            CommandManager.InvalidateRequerySuggested();
        }
    }

    public class AsyncRelayCommand : AsyncRelayCommand<object>
    {
        public AsyncRelayCommand(Func<Task> execute)
            : base(_ => execute())
        {
        }

        public AsyncRelayCommand(Func<Task> execute, Func<bool> canExecute)
            : base(_ => execute(), _ => canExecute())
        {
        }

        public new void OnCanExecuteChanged()
        {
            base.OnCanExecuteChanged();
        }
    }